<!DOCTYPE html><html lang="en" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>YLBlogs | YLBlogs</title><meta name="author" content="yhcnet"><meta name="copyright" content="yhcnet"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="计算机网络 网络模型和协议  五层协议应用层 ：为特定应用程序提供数据传输服务，例如 HTTP、DNS 等协议。数据单位为报文。 传输层 ：为进程提供通用数据传输服务。由于应用层协议很多，定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议：传输控制协议 TCP，提供面向连接、可靠的数据传输服务，数据单位为报文段；用户数据报协议 UDP，提供无连接、尽最大努力的数据传输服务，数据">
<meta property="og:type" content="article">
<meta property="og:title" content="YLBlogs">
<meta property="og:url" content="https://yehcnet.gitee.io/blog/2021/03/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/index.html">
<meta property="og:site_name" content="YLBlogs">
<meta property="og:description" content="计算机网络 网络模型和协议  五层协议应用层 ：为特定应用程序提供数据传输服务，例如 HTTP、DNS 等协议。数据单位为报文。 传输层 ：为进程提供通用数据传输服务。由于应用层协议很多，定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议：传输控制协议 TCP，提供面向连接、可靠的数据传输服务，数据单位为报文段；用户数据报协议 UDP，提供无连接、尽最大努力的数据传输服务，数据">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg">
<meta property="article:published_time" content="2021-03-24T11:36:56.393Z">
<meta property="article:modified_time" content="2021-03-24T11:36:50.746Z">
<meta property="article:author" content="yhcnet">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg"><link rel="shortcut icon" href="/blog/img/favicon.png"><link rel="canonical" href="https://yehcnet.gitee.io/blog/2021/03/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/blog/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/blog/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true},
  copy: {
    success: 'Copy successfully',
    error: 'Copy error',
    noSupport: 'The browser does not support'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: 'Just',
    min: 'minutes ago',
    hour: 'hours ago',
    day: 'days ago',
    month: 'months ago'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    jQuery: 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js',
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
    },
    fancybox: {
      js: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js',
      css: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isanchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = { 
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2021-03-24 19:36:50'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    })(window)</script><meta name="generator" content="Hexo 5.4.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="author-avatar"><img class="avatar-img" src="/blog/null" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/blog/archives/"><div class="headline">Articles</div><div class="length-num">2</div></a></div></div></div><hr/></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/blog/">YLBlogs</a></span><div id="menus"><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">No title</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">Created</span><time class="post-meta-date-created" datetime="2021-03-24T11:36:56.393Z" title="Created 2021-03-24 19:36:56">2021-03-24</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2021-03-24T11:36:50.746Z" title="Updated 2021-03-24 19:36:50">2021-03-24</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">Post View:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h3 id="计算机网络"><a href="#计算机网络" class="headerlink" title="计算机网络"></a>计算机网络</h3><ol>
<li><p><strong>网络模型和协议</strong> </p>
<h3 id="五层协议"><a href="#五层协议" class="headerlink" title="五层协议"></a>五层协议</h3><p><strong>应用层</strong> ：为特定应用程序提供数据传输服务，例如 HTTP、DNS 等协议。数据单位为报文。</p>
<p><strong>传输层</strong> ：为进程提供通用数据传输服务。由于应用层协议很多，定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议：传输控制协议 TCP，提供面向连接、可靠的数据传输服务，数据单位为报文段；用户数据报协议 UDP，提供无连接、尽最大努力的数据传输服务，数据单位为用户数据报。TCP 主要提供完整性服务，UDP 主要提供及时性服务。</p>
<p><strong>网络层</strong> ：为主机提供数据传输服务。而传输层协议是为主机中的进程提供数据传输服务。网络层把传输层传递下来的报文段或者用户数据报封装成分组。</p>
<p><strong>数据链路层</strong> ：网络层针对的还是主机之间的数据传输服务，而主机之间可以有很多链路，链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。</p>
<p><strong>物理层</strong> ：考虑的是怎样在传输媒体上传输数据比特流，而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异，使数据链路层感觉不到这些差异。</p>
<p>在向下的过程中，需要添加下层协议所需要的首部或者尾部，而在向上的过程中不断拆开首部和尾部。</p>
<p>路由器只有下面三层协议，因为路由器位于网络核心中，不需要为进程或者应用程序提供服务，因此也就不需要传输层和应用层。</p>
</li>
<li><p><strong>TCP和UDP的区别</strong> </p>
<p>用户数据报协议 UDP（User Datagram Protocol）是无连接的，尽最大可能交付，没有拥塞控制，面向报文（对于应用程序传下来的报文不合并也不拆分，只是添加 UDP 首部），支持一对一、一对多、多对一和多对多的交互通信。</p>
<p>传输控制协议 TCP（Transmission Control Protocol）是面向连接的，提供可靠交付，有流量控制，拥塞控制，提供全双工通信，面向字节流（把应用层传下来的报文看成字节流，把字节流组织成大小不等的数据块），每一条 TCP 连接只能是点对点的（一对一）。</p>
</li>
<li><p><strong>UDP如何保证可靠</strong></p>
<p>最简单的方式是在应用层模仿传输层TCP的可靠性传输。下面不考虑拥塞处理，谈谈自己的个人简单粗暴的设计。</p>
<p>解决方法：<br>1）给数据包编号，按照包的顺序接收并存储；<br>2）接收端接收到数据包后发送确认信息给发送端，发送端接收确认数据以后再继续发送下一个包，如果接收端收到的数据包的编号不是期望的编号，则要求发送端重新发送。</p>
<ul>
<li>发送：包的分片、包确认、包的重发</li>
<li>接收：包的调序、包的序号确认</li>
</ul>
<hr>
</li>
<li><p><strong>TCP、UDP、IP报文格式</strong></p>
<hr>
</li>
<li><p><strong>三次握手四次挥手</strong></p>
<p><img src="https://img-blog.csdn.net/20180717202520531?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4OTUwMzE2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="img"></p>
<p>第一次握手：建立连接时，客户端发送syn包（syn=x）到服务器，并进入SYN_SENT状态，等待服务器确认；SYN：同步序列编号（Synchronize Sequence Numbers）。</p>
<p>第二次握手：服务器收到syn包，必须确认客户的SYN（ack=x+1），同时自己也发送一个SYN包（syn=y），即SYN+ACK包，此时服务器进入SYN_RECV状态；</p>
<p>第三次握手：客户端收到服务器的SYN+ACK包，向服务器发送确认包ACK(ack=y+1），此包发送完毕，客户端和服务器进入ESTABLISHED（TCP连接成功）状态，完成三次握手。</p>
</li>
</ol>
<p>   <img src="https://img-blog.csdn.net/20180717204202563?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4OTUwMzE2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="img"></p>
<p>   1）客户端进程发出连接释放报文，并且停止发送数据。释放数据报文首部，FIN=1，其序列号为seq=u（等于前面已经传送过来的数据的最后一个字节的序号加1），此时，客户端进入FIN-WAIT-1（终止等待1）状态。 TCP规定，FIN报文段即使不携带数据，也要消耗一个序号。</p>
<p>   2）服务器收到连接释放报文，发出确认报文，ACK=1，ack=u+1，并且带上自己的序列号seq=v，此时，服务端就进入了CLOSE-WAIT（关闭等待）状态。TCP服务器通知高层的应用进程，客户端向服务器的方向就释放了，这时候处于半关闭状态，即客户端已经没有数据要发送了，但是服务器若发送数据，客户端依然要接受。这个状态还要持续一段时间，也就是整个CLOSE-WAIT状态持续的时间。</p>
<p>   3）客户端收到服务器的确认请求后，此时，客户端就进入FIN-WAIT-2（终止等待2）状态，等待服务器发送连接释放报文（在这之前还需要接受服务器发送的最后的数据）。</p>
<p>   4）服务器将最后的数据发送完毕后，就向客户端发送连接释放报文，FIN=1，ack=u+1，由于在半关闭状态，服务器很可能又发送了一些数据，假定此时的序列号为seq=w，此时，服务器就进入了LAST-ACK（最后确认）状态，等待客户端的确认。</p>
<p>   5）客户端收到服务器的连接释放报文后，必须发出确认，ACK=1，ack=w+1，而自己的序列号是seq=u+1，此时，客户端就进入了TIME-WAIT（时间等待）状态。注意此时TCP连接还没有释放，必须经过2∗∗MSL（最长报文段寿命）的时间后，当客户端撤销相应的TCB后，才进入CLOSED状态。</p>
<p>   6）服务器只要收到了客户端发出的确认，立即进入CLOSED状态。同样，撤销TCB后，就结束了这次的TCP连接。可以看到，服务器结束TCP连接的时间要比客户端早一些。</p>
<p>   <strong>为什么要进行第三次握手？</strong></p>
<p>   为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端，因而产生错误。</p>
<p>   由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器)，在传输的过程中，比如客户端发起了SYN=1创建连接的请求(第一次握手)。</p>
<p>   如果服务器端就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给客户端，这个数据包因为网络传输的原因丢失了，丢失之后客户端就一直没有接收到服务器返回的数据包。</p>
<p>   客户端可能设置了一个超时时间，时间到了就关闭了连接创建的请求。再重新发出创建连接的请求，而服务器端是不知道的，如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话，</p>
<p>   服务器端是不知道客户端有没有接收到服务器端返回的信息的。</p>
<hr>
<ol start="6">
<li><p><strong>TCP粘包</strong></p>
<p>TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包，从接收缓冲区来看，后一包数据的头紧接着前一包数据的尾，出现粘包的原因是多方面的，可能是来自发送方，也可能是来自接收方。</p>
<p>（1）发送方原因</p>
<p>TCP默认使用Nagle算法（主要作用：减少网络中报文段的数量），而Nagle算法主要做两件事：</p>
<p>​    1.只有上一个分组得到确认，才会发送下一个分组<br>​    2.收集多个小分组，在一个确认到来时一起发送<br>Nagle算法造成了发送方可能会出现粘包问题</p>
<p>（2）接收方原因</p>
<p>TCP接收到数据包时，并不会马上交到应用层进行处理，或者说应用层并不会立即处理。实际上，TCP将接收到的数据包保存在接收缓存里，然后应用程序主动从缓存读取收到的分组。这样一来，如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度，多个包就会被缓存，应用程序就有可能读取到多个首尾相接粘到一起的包。</p>
</li>
</ol>
<hr>
<ol start="7">
<li><p><strong>TCP 协议如何保证可靠传输</strong></p>
<p>校验和</p>
<pre><code>发送的数据包的二进制相加然后取反，目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错，TCP将丢弃这个报文段和不确认收到此报文段。 
</code></pre>
<p>确认应答+序列号</p>
<pre><code>TCP给发送的每一个包进行编号，接收方对数据包进行排序，把有序数据传送给应用层。 
</code></pre>
<p>超时重传</p>
<pre><code>当TCP发出一个段后，它启动一个定时器，等待目的端确认收到这个报文段。如果不能及时收到一个确认，将重发这个报文段。 
</code></pre>
</li>
</ol>
<hr>
<ol start="8">
<li><p><strong>TCP的流量和拥塞控制</strong></p>
<p><strong>流量控制</strong></p>
<p>流量控制是为了控制发送方发送速率，保证接收方来得及接收。</p>
<p>接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小，从而影响发送方的发送速率。将窗口字段设置为 0，则发送方不能发送数据。</p>
<p><strong>拥塞控制</strong></p>
<p>如果网络出现拥塞，分组将会丢失，此时发送方会继续重传，从而导致网络拥塞程度更高。因此当出现拥塞时，应当控制发送方的速率。这一点和流量控制很像，但是出发点不同。流量控制是为了让接收方能来得及接收，而拥塞控制是为了降低整个网络的拥塞程度。</p>
<p><img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/51e2ed95-65b8-4ae9-8af3-65602d452a25.jpg" alt="img"></p>
<p>TCP 主要通过四个算法来进行拥塞控制：慢开始、拥塞避免、快重传、快恢复。</p>
<p>发送方需要维护一个叫做拥塞窗口（cwnd）的状态变量，注意拥塞窗口与发送方窗口的区别：拥塞窗口只是一个状态变量，实际决定发送方能发送多少数据的是发送方窗口。</p>
<p>为了便于讨论，做如下假设：</p>
<ul>
<li>接收方有足够大的接收缓存，因此不会发生流量控制；</li>
<li>虽然 TCP 的窗口基于字节，但是这里设窗口的大小单位为报文段。</li>
</ul>
<p><img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/910f613f-514f-4534-87dd-9b4699d59d31.png" alt="img"></p>
<p><strong>慢开始与拥塞避免</strong></p>
<p>发送的最初执行慢开始，令 cwnd = 1，发送方只能发送 1 个报文段；当收到确认后，将 cwnd 加倍，因此之后发送方能够发送的报文段数量为：2、4、8 …</p>
<p>注意到慢开始每个轮次都将 cwnd 加倍，这样会让 cwnd 增长速度非常快，从而使得发送方发送的速度增长速度过快，网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh，当 cwnd &gt;= ssthresh 时，进入拥塞避免，每个轮次只将 cwnd 加 1。</p>
<p>如果出现了超时，则令 ssthresh = cwnd / 2，然后重新执行慢开始。</p>
<p><strong>快重传与快恢复</strong></p>
<p>在接收方，要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2，此时收到 M4，应当发送对 M2 的确认。</p>
<p>在发送方，如果收到三个重复确认，那么可以知道下一个报文段丢失，此时执行快重传，立即重传下一个报文段。例如收到三个 M2，则 M3 丢失，立即重传 M3。</p>
<p>在这种情况下，只是丢失个别报文段，而不是网络拥塞。因此执行快恢复，令 ssthresh = cwnd / 2 ，cwnd = ssthresh，注意到此时直接进入拥塞避免。</p>
<p>慢开始和快恢复的快慢指的是 cwnd 的设定值，而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1，而快恢复 cwnd 设定为 ssthresh。</p>
<p><img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f61b5419-c94a-4df1-8d4d-aed9ae8cc6d5.png" alt="img"></p>
</li>
</ol>
<p>   应用数据被分割成TCP认为最适合发送的数据块。 </p>
<p>   TCP的接收端会丢弃重复的数据。 </p>
<hr>
<ol start="9">
<li><p><strong>ARQ协议</strong></p>
<p>提到ARQ自动重传请求（Automatic Repeat-reQuest），就会想到TCP滑动窗口机制，没错ARQ协议是对滑动窗口的一个很好的实现。</p>
<p>ARQ协议主要包含：<strong>停等ARQ协议</strong>、<strong>连续ARQ协议</strong>，其中连续ARQ协议是为了解决停等ARQ协议信道利用率低的问题，目前传统的连续ARQ协议有<strong>回退N帧ARQ协议</strong>、<strong>选择性重传ARQ协议</strong>。</p>
<p><strong>注意：</strong> AQR协议的一个特点是：发送窗口的大小 &lt;= 窗口总数</p>
<p><strong>停等ARQ协议（stop-and-wait）</strong></p>
<p>停等ARQ协议相当于发送窗口和接收窗口大小均为1的滑动窗口协议。即发送方发送一个帧后，必须接收到一个确认帧（ACK）才能发送下一个。</p>
<p><img src="https://pic3.zhimg.com/80/v2-177f9e3104acad0e8cc10d8aea80f83a_720w.jpg" alt="img"></p>
<p><strong>原理：</strong></p>
<ol>
<li>点对点发送数据报，等待接收端回复并开始计时</li>
<li>等待开始时，发送端停止发送新数据包</li>
<li>当数据包没有成功被接收端接收时，接收端不发送ACK包，发送端将继续等待一段时间并重新发送数据包</li>
<li>重复以上步骤，直到接收到接收端发来的ACK</li>
</ol>
<p><strong>优点：</strong></p>
<p>原理简单，广泛运用于分组交换网络。</p>
<p><strong>缺点：</strong></p>
<p>较长的等待时间，使得数据传输速度低。低速传输时频道利用率较高，高速传输时频道利用率较低。</p>
<p><strong>连续ARQ协议（Continuous ARQ）</strong></p>
<p>为了克服停等ARQ协议长时间等待ACK的缺点，这个协议会连续发送一组数据包，然后再等待这些数据包的ACK。</p>
<p><img src="https://pic2.zhimg.com/80/v2-c8be7b4574097a624ab5eb2278463a11_720w.jpg" alt="img"></p>
<p><strong>回退N帧ARQ协议（Go-Back-N）</strong></p>
<p><strong>原理：</strong></p>
<ol>
<li>接收端丢弃从第一个没有收到的数据包开始的所有数据包</li>
<li>发送端收到NACK后，从NACK中指明的数据包开始重新发送</li>
</ol>
<p><strong>选择性重传ARQ协议（Selective Repeat）</strong></p>
<p><strong>原理：</strong></p>
<ol>
<li>发送端连续发送数据包但对每个数据包都设有个一个计时器</li>
<li>当在一定时间内没有收到某个数据包的ACK时，发送端只重新发送那个没有ACK的数据包</li>
</ol>
<hr>
</li>
<li><p><strong>从浏览器中输入url之后发生了什么</strong> </p>
<p>通常，在输入一个网址后，发生的事情分为六步：DNS域名解析，TCP连接，HTTP请求，接收响应结果，浏览器解析HTML，浏览器布局渲染。</p>
<ol>
<li>查找域名的IP地址</li>
</ol>
<p>我们在浏览器中输入一个网址（URL），首先，浏览器会根据输入的网址找到对应的IP地址。那么，怎样找到对应的IP地址呢？接下来我们就来看一下。</p>
<p>（1）URL的格式</p>
<p>一个URL包括协议，网络地址，资源路径；</p>
<p>协议，最常用的比如HTTP（超文本传输协议），FTP（文件传输协议）；</p>
<p>网络地址，可以是域名或IP地址，包括端口号，如果没有端口号，默认为80；</p>
<p>资源路径，可以是多种多样的。</p>
<p>（2）DNS域名解析</p>
<p>浏览器发现输入的网址不是IP地址，便向操作系统发送请求IP地址，操作系统启动DNS域名解析协议，接下来就开始DNS查询了。</p>
<p>第一步：先在各种缓存信息中查找</p>
<p>首先-本地hosts文件查找~</p>
<p>浏览器缓存——浏览器会缓存DNS一段时间，但是操作系统不会告诉浏览器缓存多长时间，这个缓存时间完全由浏览器自己决定。</p>
<p>浏览器缓存——浏览器会缓存DNS一段时间，但是操作系统不会告诉浏览器缓存多长时间，这个缓存时间完全由浏览器自己决定。</p>
<p>系统缓存——如果在浏览器中没有找到，浏览器会做一个系统调用，获得系统缓存中的记录。</p>
<p>路由器缓存——接着会将请求发给路由器，路由器一般也有自己的DNS缓存。</p>
<p>如果在缓存信息中都没有查找到，则转第二步。</p>
<p>第二步：DNS服务器查找</p>
<p>全球所有的DNS服务器组成了一个DNS域名解析系统，在这个系统中，包含了全球所有的主机和IP地址的映射。所以，先在和它直接相连的DNS服务器中查找，一般情况下，在这个DNS服务器中都可以找到，但是也不排除特殊情况。</p>
<p>如果在和本地相连的服务器上没有找到想要的IP地址，则进行递归查找。本地服务器请求比他高一级的服务器或者根服务器，根服务器查询自己的数据库，如果知道对应的IP地址，则返回信息给本地服务器，本地服务器再将信息返回给浏览器；如果没有直接找到对应的IP地址，则告诉本地服务器应该在另外的哪一个服务器上询问，然后将询问到的信息返回给浏览器。（在根服务器上一定可以找到对应的IP地址）。</p>
<ol start="2">
<li>TCP连接</li>
</ol>
<p>在知道对应的IP地址后，接下来我们就可以进行TCP连接请求了。TCP向服务器端发送SYN连接请求，经过TCP三次连接成功后，浏览器就和服务器端建立好连接了，就可以相互发送数据了。TCP的三次握手</p>
<ol start="3">
<li>浏览器发起web服务器 HTTP请求</li>
</ol>
<p>根据HTTP协议的要求，组织一个HTTP数据包，HTTP请求的报头有请求行和报文，请求行包括三部分，请求方法，URL（服务器上的资源），版本。报文有一些其他信息，比如请求正文的有效载荷长度（Content_Length），缓存信息（Cache_Control）,Cookie等。</p>
<p>（1）常见的请求方法</p>
<p><img src="https://img-blog.csdn.net/20180528172620442?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3OTU0MDg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="img"></p>
<p>（2）常见的HTTP版本</p>
<p>有两种，为HTTP/1.1和HTTP/1.0，HTTP/1.1默认的连接方式为长连接（Connection：keep-alive），而HTTP/1.0默认的连接方式为短连接（Connection：close）。</p>
<p>注：HTTP报头在结束时，会向下留下空行，这个空行也是将报头和正文分开的依据。</p>
<ol start="4">
<li>HTTP响应</li>
</ol>
<p>在通过HTTP请求服务后，服务器会向浏览器返回一个应答信息——HTTP响应。HTTP响应的报头包括三部分——版本，状态码，状态码描述。</p>
<p><img src="https://img-blog.csdn.net/20180528170903918?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3OTU0MDg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="img"></p>
<p>常见的状态和状态码</p>
<p><img src="https://img-blog.csdn.net/2018052817343529?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3OTU0MDg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="img"></p>
<p>注：如果服务器返回的响应信息为3XX，此时要转到第五步。</p>
<ol start="5">
<li>浏览器跟踪重定向地址</li>
</ol>
<p>现在浏览器知道了真正要访问的目标服务器在哪里，便向此目标服务器发送和第三步相同的报文，请求响应。</p>
<ol start="6">
<li>服务器处理请求</li>
</ol>
<p>服务器接收到获取请求，然后处理并返回一个响应。</p>
<p>这表面上看起来是一个顺向的任务，但其实这中间发生了很多有意思的东西：</p>
<p>Web 服务器软件<br>web服务器软件（像IIS和阿帕奇）接收到HTTP请求，然后确定执行什么请求处理来处理它。请求处理就是一个能够读懂请求并且能生成HTML来进行响应的程序（像ASP.NET,PHP,RUBY…）。<br>请求处理<br>请求处理阅读请求及它的参数和cookies。它会读取也可能更新一些数据，并讲数据存储在服务器上。然后，需求处理会生成一个HTML响应。</p>
<ol start="7">
<li>浏览器解析HTML</li>
</ol>
<p>就像我们平常请求网页一样，浏览器会一个一个的响应出用户请求的页面，这个页面里面有表格，有图片，有文字，也可能有视频等等。</p>
<p>浏览器按顺序解析html文件，构建DOM树，在解析到外部的css和js文件时，向服务器发起请求下载资源，若是下载css文件，则解析器会在下载的同时继续解析后面的html来构建DOM树，则在下载js文件和执行它时，解析器会停止对html的解析。</p>
<ol start="8">
<li>浏览器布局渲染</li>
</ol>
<p>布局：通过计算得到每个渲染对象在可视区域中的具体位置信息（大小和位置），这是一个递归的过程。<br>绘制：将计算好的每个像素点信息绘制在屏幕。</p>
<ol start="9">
<li>TCP断开连接</li>
</ol>
<p>在完成所有的工作后，客户端就要发送断开连接请求了，TCP释放连接需要四次挥手。</p>
</li>
<li><p><strong>DNS服务器基本流程</strong></p>
<p>先找本地dns缓存和hosts文件，如果没有，就去找个人系统配置–路由器–运营商的dns，如果没有就去从dns的根去查找，再找顶级域名服务器，依次找下去，知道找到对应的域名，获取ip地址并返回</p>
<hr>
</li>
<li><p><strong>http get和post的区别</strong> </p>
<p>本质来说没有任何区别：</p>
<ul>
<li>GET在浏览器回退时是无害的，而POST会再次提交请求。</li>
<li>GET产生的URL地址可以添加书签，而POST不可以。</li>
<li>GET请求会被浏览器主动cache，而POST不会，除非手动设置。</li>
<li>GET请求只能进行url编码，而POST支持多种编码方式。</li>
<li>GET请求参数会被完整保留在浏览器历史记录里，而POST中的参数不会被保留。</li>
<li>GET请求在URL中传送的参数是有长度限制的，而POST么有。</li>
<li>对参数的数据类型，GET只接受ASCII字符，而POST没有限制。</li>
<li>GET比POST更不安全，因为参数直接暴露在URL上，所以不能用来传递敏感信息。</li>
<li>GET参数通过URL传递，POST放在Request body中。</li>
</ul>
</li>
<li><p><strong>cookies和session的关系</strong> </p>
<p>cookie 和session 的区别：<br>1、cookie数据存放在客户的浏览器上，session数据放在服务器上。<br>2、cookie不是很安全，别人可以分析存放在本地的COOKIE并进行COOKIE欺骗<br>考虑到安全应当使用session。<br>3、session会在一定时间内保存在服务器上。当访问增多，会比较占用你服务器的性能<br>考虑到减轻服务器性能方面，应当使用COOKIE。<br>4、单个cookie保存的数据不能超过4K，很多浏览器都限制一个站点最多保存20个cookie。</p>
<p>cookie 和session 的联系：<br>session是通过cookie来工作的<br>session和cookie之间是通过 $_COOKIE[‘PHPSESSID’] 来联系的，通过 $_COOKIE[‘PHPSESSID’]可以知道session的id，从而获取到其他的信息。<br>在购物网站中通常将用户加入购物车的商品联通session_id记录到数据库中，当用户再次访问是，通过sessionid就可以查找到用户上次加入购物车的商品。因为sessionid是唯一的，记录到数据库中就可以根据这个查找了。</p>
</li>
<li><p><strong>服务器怎么知道客户端已经发送数据完毕？</strong> </p>
</li>
<li><p><strong>数字证书、签名</strong> </p>
<h4 id="数字签名"><a href="#数字签名" class="headerlink" title="数字签名"></a>数字签名</h4><p>接着聊上面发邮件的例子，假设A用自己的私钥对Email加密发送，这存在下面问题：</p>
<ul>
<li><p>对文件本身加密可能是个耗时过程，比如这封Email足够大，那么私钥加密整个文件以及拿到文件后的解密无疑是巨大的开销。<br>数字签名可以解决这个问题：<br>1.A先对这封Email执行哈希运算得到hash值简称“摘要”，取名h1<br>2.然后用自己私钥对摘要加密，生成的东西叫“数字签名”<br>3.把数字签名加在Email正文后面，一起发送给B<br>（当然，为了防止邮件被窃听你可以用继续公钥加密，这个不属于数字签名范畴）<br>4.B收到邮件后用A的公钥对数字签名解密，成功则代表Email确实来自A，失败说明有人冒充<br>5.B对邮件正文执行哈希运算得到hash值，取名h2<br>6.B 会对比第4步数字签名的hash值h1和自己运算得到的h2，一致则说明邮件未被篡改。</p>
<p><img src="https://upload-images.jianshu.io/upload_images/4943911-697a85b6cafa5c07.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/758/format/webp" alt="img"></p>
<p>图1.png</p>
</li>
</ul>
<p>其实就是利用算法（不一定是非对称算法）对原文hash值加密，然后附着到原文的一段数据。数字签名的作用就是验证数据来源以及数据完整性！解密过程则称为数字签名验证。<br> 几点疑惑：</p>
<ol>
<li>如果中间人同时篡改了Email正文和数字签名，那B收到邮件无法察觉啊。<br>答案：数字签名的生成需要对方私钥，所以数字签名很难被伪造。万一私钥泄漏了呢，不好意思，你私钥都能弄丢了那这篇文章当我白写。（私钥绝对保密不参与传输）</li>
<li>公钥是公开的并且可以自行导入到电脑，如果有人比如C偷偷在B的电脑用自己公钥替换了A的公钥，然后用自己的私钥给B发送Email，这时B收到邮件其实是被C冒充的但是他无法察觉。<br>答案：确实存在这种情况！解决办法就是数字证书</li>
</ol>
<h4 id="数字证书"><a href="#数字证书" class="headerlink" title="数字证书"></a>数字证书</h4><p>上面第2点描述的安全漏洞根源就是A的公钥很容易被替换！那么数字证书是怎么生成的呢？以及如何配合数字签名工作呢？</p>
<ol>
<li><p>首先A去找”证书中心”（certificate authority，简称CA），为公钥做认证。证书中心用自己的私钥，对A的公钥和一些相关信息一起加密，生成”数字证书”（Digital Certificate）：</p>
<p><img src="https://upload-images.jianshu.io/upload_images/4943911-9d6bfc9fe32b5d59.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/235/format/webp" alt="img"></p>
<p>图2.png</p>
</li>
<li><p>A在邮件正文下方除了数字签名，另外加上这张数字证书</p>
<p><img src="https://upload-images.jianshu.io/upload_images/4943911-051acca03db99fd1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/268/format/webp" alt="img"></p>
<p>image.png</p>
</li>
<li><p>B收到Email后用CA的公钥解密这份数字证书，拿到A的公钥，然后验证数字签名，后面流程就和图1的流程一样了，不再赘述。</p>
</li>
</ol>
</li>
<li><p><strong>HTTP1.0、1.1、2.0之间的区别</strong> </p>
<p>HTTP1.0与HTTP 1.1的主要区别</p>
<pre><code>长连接
节约带宽
HOST域
</code></pre>
<p>HTTP1.1与HTTP 2.0的主要区别</p>
<pre><code>多路复用
二进制分帧
首部压缩
服务器推送
</code></pre>
<p><strong>一、HTTP1.0与HTTP 1.1的主要区别</strong></p>
<blockquote>
<p>长连接</p>
</blockquote>
<p>HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接，而HTTP1.1默认支持长连接。</p>
<p>HTTP是基于TCP/IP协议的，创建一个TCP连接是需要经过三次握手的,有一定的开销，如果每次通讯都要重新建立连接的话，对性能有影响。因此最好能维持一个长连接，可以用一个长连接来发多个请求。</p>
<blockquote>
<p>节约带宽</p>
</blockquote>
<p>HTTP 1.1支持只发送header信息(不带任何body信息)，如果服务器认为客户端有权限请求服务器，则返回100，否则返回401。客户端如果接收到100，才开始把请求body发送到服务器。</p>
<p>这样当服务器返回401的时候，客户端就可以不用发送请求body了，节约了带宽。</p>
<p>另外HTTP还支持传送内容的一部分。这样当客户端已经有一部分的资源后，只需要跟服务器请求另外的部分资源即可。这是支持文件断点续传的基础。</p>
<blockquote>
<p>HOST域</p>
</blockquote>
<p>现在可以用web server（例如tomat），设置虚拟站点是非常常见的，也即是说，web server上的多个虚拟站点可以共享同一个ip和端口。</p>
<p>HTTP1.0是没有host域的，HTTP1.1才支持这个参数。</p>
<p><strong>一、HTTP1.1与HTTP 2.0的主要区别</strong></p>
<blockquote>
<p>HTTP 2.0的出现，相比于HTTP 1.x,大幅度的提升了web性能。在与HTTP/1.1完全语义兼容的基础上，进一步减少了网络延迟。而对于前端开发人员来说，无疑减少了在前端方面的优化工作。</p>
</blockquote>
<p>下面基于HTTP 2.0协议的几个基本技术点来说明HTTP1.1与HTTP2.0的区别</p>
<blockquote>
<p>多路复用</p>
</blockquote>
<p>允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息。</p>
<p>众所周知，在HTTP/1.1协议中，浏览器客户端在同一时间针对同一域名的请求有一定数据限制。超过限制数目的请求会被阻塞。</p>
<p>HTTP2.0使用了多路复用的技术，做到同一个连接并发处理多个请求，而且并发请求的数量比HTTP1.1大了好几个数量级。</p>
<p>当然HTTP1.1也可以多建立几个TCP连接，来支持处理更多并发的请求，但是创建TCP连接本身也是有开销的。</p>
<p>TCP连接有一个预热和保护的过程，先检查数据是否传送成功，一旦成功过，则慢慢加大传输速度。因此对应瞬时并发的连接，服务器的响应就会变慢。所以最好能使用一个建立好的连接，并且这个连接可以支持瞬时并发的请求。</p>
<p>在过去，HTTP性能优化的关键并不在于高带宽，而是低延迟。</p>
<p>单连接多资源的方式，减少服务端的链接压力,内存占用更少,连接吞吐量更大</p>
<p>由于 TCP 连接的减少而使网络拥塞状况得以改善，同时慢启动时间的减少,使拥塞和丢包恢复速度更快</p>
<blockquote>
<p>二进制分帧</p>
</blockquote>
<p>在不改动HTTP/1.x的语义、语法、状态吗、URI以及首部字段……的情况下，HTTP/2是如何作做到“突破HTTP1.1的性能限制，改进传输性能，实现低延迟和高吞吐量”的？</p>
<p>关键之一就是在应用层（HTTP/2）和传输层（TCP or UDP）之间增加一个二进制分帧层。</p>
<blockquote>
<p>首部压缩</p>
</blockquote>
<p>HTTP1.1不支持header数据的压缩，HTTP2.0使用HPACK算法对header的数据进行压缩，这样数据体积小了，在网络上传输就会更快。</p>
<blockquote>
<p> 服务器推送</p>
</blockquote>
<p>服务端推送是一种在客户端请求之前发送数据的机制。</p>
<p>在HTTP/2中，服务器可以对客户端的一个请求发送多个响应。</p>
<p>Server Push 让HTTP1.x时代使用内嵌资源的优化手段变得没有意义；</p>
<p>意思是说，当我们对支持HTTP2.0的web server请求数据的时候，服务器会顺便把一些客户端需要的资源一起推送到客户端，免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源。</p>
<p>服务器推送可以缓存，并且在遵循同源的情况下，不同页面之间可以共享缓存。</p>
<p>因此当客户端需要的数据已缓存时，客户端直接从本地加载这些资源就可以了，不用走网络，速度自然是快很多的。</p>
</li>
<li><p><strong>HTTP状态码</strong> </p>
<p><img src="https://img-blog.csdn.net/2018052817343529?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3OTU0MDg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="img"></p>
<table>
<thead>
<tr>
<th>100</th>
<th>Continue</th>
<th>继续。<a target="_blank" rel="noopener" href="http://www.dreamdu.com/webbuild/client_vs_server/">客户端</a>应继续其请求</th>
</tr>
</thead>
<tbody><tr>
<td>101</td>
<td>Switching Protocols</td>
<td>切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议，例如，切换到HTTP的新版本协议</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>200</th>
<th>OK</th>
<th>请求成功。一般用于GET与POST请求</th>
</tr>
</thead>
<tbody><tr>
<td>201</td>
<td>Created</td>
<td>已创建。成功请求并创建了新的资源</td>
</tr>
<tr>
<td>202</td>
<td>Accepted</td>
<td>已接受。已经接受请求，但未处理完成</td>
</tr>
<tr>
<td>203</td>
<td>Non-Authoritative Information</td>
<td>非授权信息。请求成功。但返回的meta信息不在原始的服务器，而是一个副本</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>300</th>
<th>Multiple Choices</th>
<th>多种选择。请求的资源可包括多个位置，相应可返回一个资源特征与地址的列表用于用户终端（例如：浏览器）选择</th>
</tr>
</thead>
<tbody><tr>
<td>301</td>
<td>Moved Permanently</td>
<td>永久移动。请求的资源已被永久的移动到新URI，返回信息会包括新的URI，浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替</td>
</tr>
<tr>
<td>302</td>
<td>Found</td>
<td>临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI</td>
</tr>
<tr>
<td>303</td>
<td>See Other</td>
<td>查看其它地址。与301类似。使用GET和POST请求查看</td>
</tr>
<tr>
<td>304</td>
<td>Not Modified</td>
<td>未修改。所请求的资源未修改，服务器返回此状态码时，不会返回任何资源。客户端通常会缓存访问过的资源，通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>400</th>
<th>Bad Request</th>
<th>客户端请求的语法错误，服务器无法理解</th>
</tr>
</thead>
<tbody><tr>
<td>401</td>
<td>Unauthorized</td>
<td>请求要求用户的身份认证</td>
</tr>
<tr>
<td>402</td>
<td>Payment Required</td>
<td>保留，将来使用</td>
</tr>
<tr>
<td>403</td>
<td>Forbidden</td>
<td>服务器理解请求客户端的请求，但是拒绝执行此请求</td>
</tr>
<tr>
<td>404</td>
<td>Not Found</td>
<td>服务器无法根据客户端的请求找到资源（网页）。通过此代码，网站设计人员可设置”您所请求的资源无法找到”的个性页面</td>
</tr>
<tr>
<td>405</td>
<td>Method Not Allowed</td>
<td>客户端请求中的方法被禁止</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>500</th>
<th>Internal Server Error</th>
<th>服务器内部错误，无法完成请求</th>
</tr>
</thead>
<tbody><tr>
<td>501</td>
<td>Not Implemented</td>
<td>服务器不支持请求的功能，无法完成请求</td>
</tr>
<tr>
<td>502</td>
<td>Bad Gateway</td>
<td>作为网关或者代理工作的服务器尝试执行请求时，从远程服务器接收到了一个无效的响应</td>
</tr>
</tbody></table>
</li>
<li><p><strong>http请求报文有什么？</strong> </p>
<p>HTTP 报文包括以下三个部分：</p>
<ul>
<li><p>起始行<br>报文的第一行就是起始行,在请求报文中用来说明要做些什么,在响应报文中说明出现了什么情况。</p>
<p>GET  <a target="_blank" rel="noopener" href="http://www.baidu.com/">www.baidu.com</a> HTTP/1.1</p>
</li>
<li><p>头部<br>起始行后面有零个或多个首部字段。每个首部字段都包含一个名字和一个值,为了便于解析,两者之间用冒号(:)来分隔。首部以一个空行结束。添加一个首部字段和添加新行一样简单。</p>
<p>User-Agent：浏览器的具体类型</p>
<p>Accept：浏览器支持哪些数据类型</p>
<p>Accept-Charset：浏览器采用的是哪种编码　　如：Accept-Charset: ISO-8859-1</p>
<p>Accept-Encoding：浏览器支持解码的数据压缩格式　　如：Accept-Encoding: gzip, deflate</p>
<p>Accept-Language：浏览器的语言环境　　如：Accept-Language zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3</p>
<p>Host：请求的主机名，允许多个域名同处一个IP地址，即虚拟主机。Host:<a target="_blank" rel="noopener" href="http://www.baidu.com/">www.baidu.com</a></p>
<p>Connection：表示是否需要持久连接。Keep-Alive/close，HTTP1.1默认是持久连接，它可以利用持久连接的优点，当页面包含多个元素时（例如Applet，图片），显著地减少下载所需要的时间。要实现这一点，Servlet需要在应答中发送一个Content-Length头，最简单的实现方法是：先把内容写入ByteArrayOutputStream，然后在正式写出内容之前计算它的大小。如：Connection: Keep-Alive</p>
<p>Content-Length：表示请求消息正文的长度。对于POST请求来说Content-Length必须出现。</p>
<p>Content-Type：WEB服务器告诉浏览器自己响应的对象的类型和字符集。例如：Content-Type: Content-Encoding：WEB服务器表明自己使用了什么压缩方法（gzip，deflate）压缩响应中的对象。例如：Content-Encoding：gzip</p>
<p>Content-Language：WEB服务器告诉浏览器自己响应的对象的语言。</p>
<p>Cookie：最常用的请求头，浏览器每次都会将cookie发送到服务器上，允许服务器在客户端存储少量数据。</p>
<p>Referer：包含一个URL，用户从该URL代表的页面出发访问当前请求的页面。服务器能知道你是从哪个页面过来的。Referer: <a target="_blank" rel="noopener" href="http://www.baidu.com/">http://www.baidu.com/</a></p>
</li>
<li><p>主体<br>空行之后就是可选的报文主体了,其中包含了所有类型的数据。请求主体中包括 了要发送给 Web 服务器的数据;响应主体中装载了要返回给客户端的数据。起始行和首部都是文本形式且都是结构化的,而主体则不同,主体中可以包含任意 的二进制数据(比如图片、视频、音轨、软件程序)。当然,主体中也可以包含 文本。</p>
<p>name=username;password=userpassword</p>
</li>
</ul>
</li>
<li><p>**http缓存</p>
</li>
</ol>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">Author: </span><span class="post-copyright-info"><a href="mailto:undefined">yhcnet</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">Link: </span><span class="post-copyright-info"><a href="https://yehcnet.gitee.io/blog/2021/03/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">https://yehcnet.gitee.io/blog/2021/03/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">Copyright Notice: </span><span class="post-copyright-info">All articles in this blog are licensed under <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a> unless stating additionally.</span></div></div><div class="tag_share"><div class="post-meta__tag-list"></div><div class="post_share"><div class="social-share" data-image="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="next-post pull-full"><a href="/blog/2021/03/24/hello-world/"><img class="next-cover" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" onerror="onerror=null;src='/blog/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">Next Post</div><div class="next_info">Hello World</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="card-info-avatar is-center"><img class="avatar-img" src="/blog/null" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="avatar"/><div class="author-info__name">yhcnet</div><div class="author-info__description"></div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/blog/archives/"><div class="headline">Articles</div><div class="length-num">2</div></a></div></div><a class="button--animated" id="card-info-btn" target="_blank" rel="noopener" href="http://jysx.xyz"><i class="fab fa-github"></i><span>Follow Me</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>Announcement</span></div><div class="announcement_content">This is my Blog with Hexo!</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>Catalog</span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C"><span class="toc-number">1.</span> <span class="toc-text">计算机网络</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%94%E5%B1%82%E5%8D%8F%E8%AE%AE"><span class="toc-number">2.</span> <span class="toc-text">五层协议</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D"><span class="toc-number">2.1.</span> <span class="toc-text">数字签名</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%95%B0%E5%AD%97%E8%AF%81%E4%B9%A6"><span class="toc-number">2.2.</span> <span class="toc-text">数字证书</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>Recent Post</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/blog/2021/03/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/" title="No title"><img src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="No title"/></a><div class="content"><a class="title" href="/blog/2021/03/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/" title="No title">No title</a><time datetime="2021-03-24T11:36:56.393Z" title="Created 2021-03-24 19:36:56">2021-03-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2021/03/24/hello-world/" title="Hello World"><img src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="Hello World"/></a><div class="content"><a class="title" href="/blog/2021/03/24/hello-world/" title="Hello World">Hello World</a><time datetime="2021-03-24T08:28:33.498Z" title="Created 2021-03-24 16:28:33">2021-03-24</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2021 By yhcnet</div><div class="framework-info"><span>Framework </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>Theme </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="Read Mode"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="Switch Between Light And Dark Mode"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="Toggle between single-column and double-column"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="Setting"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="Table Of Contents"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="Back To Top"><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/blog/js/utils.js"></script><script src="/blog/js/main.js"></script><div class="js-pjax"></div><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>